package com.springboot.cli.controller;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ContainerInfoFetcher {
    
    /**
     * 容器信息数据类
     */
    public static class ContainerInfo {
        private String containerId;
        private String containerIp;
        private String hostIp;
        
        public ContainerInfo(String containerId, String containerIp, String hostIp) {
            this.containerId = containerId;
            this.containerIp = containerIp;
            this.hostIp = hostIp;
        }
        
        // Getters
        public String getContainerId() { return containerId; }
        public String getContainerIp() { return containerIp; }
        public String getHostIp() { return hostIp; }
        
        @Override
        public String toString() {
            return String.format("ContainerInfo{id='%s', containerIp='%s', hostIp='%s'}", 
                               containerId, containerIp, hostIp);
        }
    }
    
    /**
     * 获取完整的容器信息
     */
    public static ContainerInfo getContainerInfo() {
        String containerId = getContainerId();
        String containerIp = getContainerIp();
        String hostIp = getHostIp();
        
        return new ContainerInfo(containerId, containerIp, hostIp);
    }
    
    /**
     * 获取容器ID
     */
    public static String getContainerId() {
        // 方法1: 从cgroup获取
        String containerId = getContainerIdFromCGroup();
        if (containerId != null && !containerId.isEmpty()) {
            return containerId.length() > 12 ? containerId.substring(0, 12) : containerId;
        }
        
        // 方法2: 从mountinfo获取
        containerId = getContainerIdFromMountInfo();
        if (containerId != null && !containerId.isEmpty()) {
            return containerId.length() > 12 ? containerId.substring(0, 12) : containerId;
        }
        
        // 方法3: 从环境变量获取
        containerId = getContainerIdFromEnv();
        if (containerId != null && !containerId.isEmpty()) {
            return containerId.length() > 12 ? containerId.substring(0, 12) : containerId;
        }
        
        return null;
    }
    
    /**
     * 从cgroup文件中提取容器ID
     */
    private static String getContainerIdFromCGroup() {
        try {
            List<String> lines = Files.readAllLines(Paths.get("/proc/self/cgroup"));
            Pattern pattern = Pattern.compile(".*/([0-9a-f]{64})|.*docker[/-]([0-9a-f]{64})");
            
            for (String line : lines) {
                Matcher matcher = pattern.matcher(line);
                if (matcher.find()) {
                    return matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
                }
            }
        } catch (Exception e) {
            // 忽略异常，尝试其他方法
        }
        return null;
    }
    
    /**
     * 从mountinfo文件中提取容器ID
     */
    private static String getContainerIdFromMountInfo() {
        try {
            List<String> lines = Files.readAllLines(Paths.get("/proc/self/mountinfo"));
            Pattern pattern = Pattern.compile(".*/containers/([0-9a-f]{64})/");
            
            for (String line : lines) {
                Matcher matcher = pattern.matcher(line);
                if (matcher.find()) {
                    return matcher.group(1);
                }
            }
        } catch (Exception e) {
            // 忽略异常，尝试其他方法
        }
        return null;
    }
    
    /**
     * 从环境变量中获取容器ID
     */
    private static String getContainerIdFromEnv() {
        String[] envVars = {
            "HOSTNAME",           // Docker容器ID通常设置为hostname
            "CONTAINER_ID"        // 自定义环境变量
        };
        
        for (String envVar : envVars) {
            String value = System.getenv(envVar);
            if (value != null && !value.isEmpty()) {
                return value;
            }
        }
        return null;
    }
    
    /**
     * 获取容器IP地址
     */
    public static String getContainerIp() {
        // 方法1: 从环境变量获取
        String ip = getContainerIpFromEnv();
        if (ip != null && isValidIpAddress(ip)) {
            return ip;
        }
        
        // 方法2: 从网络接口获取
        ip = getContainerIpFromNetworkInterfaces();
        if (ip != null) {
            return ip;
        }
        
        // 方法3: 获取本地地址
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            return "127.0.0.1";
        }
    }
    
    /**
     * 从环境变量获取容器IP
     */
    private static String getContainerIpFromEnv() {
        String[] envVars = {
            "CONTAINER_IP",
            "POD_IP"  // Kubernetes环境
        };
        
        for (String envVar : envVars) {
            String ip = System.getenv(envVar);
            if (ip != null && isValidIpAddress(ip)) {
                return ip;
            }
        }
        return null;
    }
    
    /**
     * 从网络接口获取容器IP
     */
    private static String getContainerIpFromNetworkInterfaces() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            
            while (interfaces.hasMoreElements()) {
                NetworkInterface networkInterface = interfaces.nextElement();
                
                // 跳过回环接口
                if (networkInterface.isLoopback()) {
                    continue;
                }
                
                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress address = addresses.nextElement();
                    String ip = address.getHostAddress();
                    
                    // 返回第一个非回环IPv4地址
                    if (!address.isLoopbackAddress() && ip.contains(".")) {
                        // 排除docker网关地址
                        if (!ip.startsWith("172.17.0.1")) {
                            return ip;
                        }
                    }
                }
            }
        } catch (SocketException e) {
            // 忽略异常
        }
        return null;
    }
    
    /**
     * 获取宿主机IP
     */
    public static String getHostIp() {
        // 方法1: 从环境变量获取
        String hostIp = getHostIpFromEnv();
        if (hostIp != null) {
            return hostIp;
        }
        
        // 方法2: 通过DNS解析
        hostIp = getHostIpFromDockerDns();
        if (hostIp != null) {
            return hostIp;
        }
        
        // 方法3: 从/etc/hosts获取
        hostIp = getHostIpFromEtcHosts();
        if (hostIp != null) {
            return hostIp;
        }
        
        // 方法4: 从网关获取
        hostIp = getHostIpFromGateway();
        if (hostIp != null) {
            return hostIp;
        }
        
        // 默认返回Docker网关地址
        return "172.17.0.1";
    }
    
    /**
     * 通过环境变量获取宿主机IP
     */
    private static String getHostIpFromEnv() {
        String[] envVars = {
            "HOST_IP",
            "DOCKER_HOST_IP"
        };
        
        for (String envVar : envVars) {
            String ip = System.getenv(envVar);
            if (ip != null && isValidIpAddress(ip)) {
                return ip;
            }
        }
        return null;
    }
    
    /**
     * 通过Docker DNS解析宿主机IP
     */
    private static String getHostIpFromDockerDns() {
        try {
            InetAddress address = InetAddress.getByName("host.docker.internal");
            return address.getHostAddress();
        } catch (UnknownHostException e) {
            return null;
        }
    }
    
    /**
     * 通过/etc/hosts文件获取宿主机IP
     */
    private static String getHostIpFromEtcHosts() {
        try {
            List<String> lines = Files.readAllLines(Paths.get("/etc/hosts"));
            Pattern pattern = Pattern.compile("^(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+host\\.docker\\.internal");
            
            for (String line : lines) {
                Matcher matcher = pattern.matcher(line.trim());
                if (matcher.find()) {
                    return matcher.group(1);
                }
            }
        } catch (Exception e) {
            // 忽略异常
        }
        return null;
    }
    
    /**
     * 通过网关获取宿主机IP
     */
    private static String getHostIpFromGateway() {
        try {
            Process process = Runtime.getRuntime().exec("ip route show default");
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            
            String line;
            Pattern pattern = Pattern.compile("default via (\\d+\\.\\d+\\.\\d+\\.\\d+)");
            
            while ((line = reader.readLine()) != null) {
                Matcher matcher = pattern.matcher(line);
                if (matcher.find()) {
                    return matcher.group(1);
                }
            }
        } catch (Exception e) {
            // 忽略异常
        }
        return null;
    }
    
    /**
     * 验证IP地址格式
     */
    private static boolean isValidIpAddress(String ip) {
        return ip != null && ip.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
    }
    
    public static void main(String[] args) {
        ContainerInfo info = getContainerInfo();
        System.out.println(info);
    }
}